package com.apt.action;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.struts2.dispatcher.SessionMap;

import com.apt.common.AptException;
import com.apt.facade.DataStoreHelper;
import com.apt.model.Question;

public class ExamAction extends AptBaseAction {
	private static final long serialVersionUID = 1L;
	private static int paginationCount = 2;
	
	private List<Question> questions;	
	private int totalQuestions;	
	private Map<String, String> answersMap = new HashMap<String, String>();
	
	private String testId;
	
	private int remainingTime;	
	private int counter;

	public ExamAction() {

		super();
		//System.out.println("New instance of ExamAction created");

	}
	
	public Map<String, String> getAnswersMap() {
		return answersMap;
	}

	public void setAnswersMap(Map<String, String> answersMap) {
		this.answersMap = answersMap;
	}

	public List<Question> getQuestions() {
		return questions;
	}
	

	public String getTestId() {
		return testId;
	}

	public void setTestId(String testId) {
		this.testId = testId;
	}


	public int getRemainingTime() {
		return remainingTime;
	}

	public void setRemainingTime(int remainingTime) {
		this.remainingTime = remainingTime;
	}

	public int getCounter() {
		return counter;
	}

	public void setCounter(int counter) {
		this.counter = counter;
	}

	public String processBegin() {
		//System.out.println("Session in BEGIN:" + session);
		//System.out.println("TestId is:"+ testId);
		int duration = 0;
		try{
		duration = DataStoreHelper.getTestDuration(Integer.parseInt(testId));
		duration = duration * 60;
		placeQuestionsInSession(true);
		}
		catch(AptException apt)
		{
			invalidateSession();
			addActionError(apt.getMessage());
			return "error";

			
		}
		session.put("start", 0);
		int last = questions.size() - 1;
		int end = paginationCount - 1;
		if (end > last) {
			end = last;
		}
		
		session.put("end", end);
		
		session.put("duration", duration);
		session.put("first", "true");
		session.put("counter", 0);
		
		//System.out.println("The session in BEGIN is:" + session);
		//System.out.println("The userid in BEGIN is:" + session.get("loggedInUser"));
		
		return "success";

	}

	public String processNext() {
		// System.out.println("Begin of processNext session is:" + session);
		try{
		placeQuestionsInSession(false);
		//System.out.println("The session in NEXT is:" + session);
		//System.out.println("The userid in NEXT is:" + session.get("loggedInUser"));
		}
		catch(AptException apt)
		{
			invalidateSession();
			addActionError(apt.getMessage());
			return "error";

			
		}
		int currentEnd = (Integer) session.get("end");
		session.put("start", currentEnd + 1);
		int end = currentEnd + paginationCount;
		int last = questions.size() - 1;
		if (end > last) {
			end = last;
		}
		session.put("end", end);
		// System.out.println("End is:"+ end);
		// System.out.println("End of processNext session is:" + session);
		//printChoices();
		return "success";

	}

	public String processPrev() {
		//System.out.println("Begin of processPrev session is:" + session);
		try
		{
		placeQuestionsInSession(false);
		}
		catch(AptException apt)
		{
			invalidateSession();
			addActionError(apt.getMessage());
			return "error";

		
		}
		int currentEnd = (Integer) session.get("end");
		int currentStart = (Integer) session.get("start");
		int start = currentStart - paginationCount;
		int end = start + (paginationCount - 1);
		session.put("start", start);
		session.put("end", end);
		// System.out.println("End is:"+ end);
		// System.out.println("End of processNext session is:" + session);
		//printChoices();
		return "success";

	}

	public String processFinish() {
		System.out.println("The userid in FINISH is:" + session.get("loggedInUser"));
		try{
		placeQuestionsInSession(false);
		//System.out.println("The session in FINISH is:" + session);		
		String userId=(String)session.get("loggedInUser");
		String testId=(String)session.get("testId");
		DataStoreHelper.updateTestResults(userId, Integer.parseInt(testId), totalQuestions, questions);
		invalidateSession();
		
		
		}
		catch(AptException apt)
		{
			invalidateSession();
			addActionError(apt.getMessage());
			return "error";

			
		}
		//printChoices();
		return "success";

	}

	private void placeQuestionsInSession(boolean start) throws AptException {
		
		String user = (String)session.get("loggedInUser");		
		//Handle cases when logged in user is null
		if(user == null )
		{
			
			System.out.println("SESSION IS INVALID");			
			throw new AptException("Your session has expired!Please login again.");	
			
		}
		
		Object ques = session.get("questionList");
		if (ques == null) {
			if (!start) {
				System.out.println("SESSION IS INVALID");				
				throw new AptException("Your session has expired!Please login again.");			
				
				// TODO: Need to handle this case. This is a serious issue since
				// session is being corrupted

			}
			if(testId == null || testId.isEmpty())
			{
				
				throw new AptException("InValid TestId:"+ testId);
				
			}
			questions = DataStoreHelper.getQuestionsFromDataStore(testId);
			Collections.shuffle(questions);
			totalQuestions = questions.size();
			session.put("questionList", questions);
			session.put("totalQuestions", totalQuestions);
			session.put("testId", testId); //Need the testId for updating tables
		} else {
			questions = (List<Question>) ques;
			totalQuestions = (Integer) session.get("totalQuestions");

			for (int qcount = 0; qcount < questions.size(); qcount++) {
				Question each = questions.get(qcount);
				String optId = answersMap.get(each.getQuestionId());
				//System.out.println("OptId from answerMap:" + optId);
				if(optId != null)
				{
					each.setStudentChoice(optId);
					questions.set(qcount, each);
				}
			}
			session.put("questionList", questions);
			session.put("duration", remainingTime);
			session.put("first", "false");
			session.put("counter", counter);
		}
	}

	private void invalidateSession()
	{
		if(session instanceof SessionMap )
		{
			
			((SessionMap) session).invalidate();
			System.out.println("Session Invalidated");
			
		}
		
	}

	private void printChoices() {
		
		
		for(Question q: questions)
		{
			System.out.println("Choices:" + q.getStudentChoice());
			
		}
		
	}

}
